; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
; RUN: llc -mtriple aarch64 -aarch64-enable-atomic-cfg-tidy=0 -stop-after=irtranslator -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s

define i32 @test_bittest(i16 %p) {
  ; CHECK-LABEL: name: test_bittest
  ; CHECK: bb.1 (%ir-block.0):
  ; CHECK:   successors: %bb.4(0x1b6db6db), %bb.5(0x64924925)
  ; CHECK:   liveins: $w0
  ; CHECK:   [[COPY:%[0-9]+]]:_(s32) = COPY $w0
  ; CHECK:   [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
  ; CHECK:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 114
  ; CHECK:   [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
  ; CHECK:   [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
  ; CHECK:   [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC]](s16)
  ; CHECK:   [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
  ; CHECK:   [[SUB:%[0-9]+]]:_(s32) = G_SUB [[ZEXT]], [[C3]]
  ; CHECK:   [[ZEXT1:%[0-9]+]]:_(s64) = G_ZEXT [[SUB]](s32)
  ; CHECK:   [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 59
  ; CHECK:   [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(ugt), [[SUB]](s32), [[C4]]
  ; CHECK:   G_BRCOND [[ICMP]](s1), %bb.4
  ; CHECK:   G_BR %bb.5
  ; CHECK: bb.4 (%ir-block.0):
  ; CHECK:   successors: %bb.3(0x40000000), %bb.2(0x40000000)
  ; CHECK:   [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[ZEXT]](s32), [[C]]
  ; CHECK:   G_BRCOND [[ICMP1]](s1), %bb.3
  ; CHECK:   G_BR %bb.2
  ; CHECK: bb.5 (%ir-block.0):
  ; CHECK:   successors: %bb.3(0x745d1746), %bb.4(0x0ba2e8ba)
  ; CHECK:   [[C5:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
  ; CHECK:   [[SHL:%[0-9]+]]:_(s64) = G_SHL [[C5]], [[ZEXT1]](s64)
  ; CHECK:   [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 866239240827043840
  ; CHECK:   [[AND:%[0-9]+]]:_(s64) = G_AND [[SHL]], [[C6]]
  ; CHECK:   [[C7:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
  ; CHECK:   [[ICMP2:%[0-9]+]]:_(s1) = G_ICMP intpred(ne), [[AND]](s64), [[C7]]
  ; CHECK:   G_BRCOND [[ICMP2]](s1), %bb.3
  ; CHECK:   G_BR %bb.4
  ; CHECK: bb.2.sw.epilog:
  ; CHECK:   $w0 = COPY [[C2]](s32)
  ; CHECK:   RET_ReallyLR implicit $w0
  ; CHECK: bb.3.cb1:
  ; CHECK:   $w0 = COPY [[C1]](s32)
  ; CHECK:   RET_ReallyLR implicit $w0
  switch i16 %p, label %sw.epilog [
    i16 58, label %cb1
    i16 59, label %cb1
    i16 47, label %cb1
    i16 48, label %cb1
    i16 50, label %cb1
    i16 114, label %cb1
  ]
sw.epilog:
  ret i32 0

cb1:
  ret i32 42
}


declare void @callee()

define void @test_bittest_2_bt(i32 %p) {
  ; CHECK-LABEL: name: test_bittest_2_bt
  ; CHECK: bb.1.entry:
  ; CHECK:   successors: %bb.5(0x345d1746), %bb.6(0x4ba2e8ba)
  ; CHECK:   liveins: $w0
  ; CHECK:   [[COPY:%[0-9]+]]:_(s32) = COPY $w0
  ; CHECK:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 176
  ; CHECK:   [[SUB:%[0-9]+]]:_(s32) = G_SUB [[COPY]], [[C]]
  ; CHECK:   [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 15
  ; CHECK:   [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(ugt), [[SUB]](s32), [[C1]]
  ; CHECK:   G_BRCOND [[ICMP]](s1), %bb.5
  ; CHECK:   G_BR %bb.6
  ; CHECK: bb.5.entry:
  ; CHECK:   successors: %bb.4(0x0ccccccd), %bb.7(0x73333333)
  ; CHECK:   [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
  ; CHECK:   [[SUB1:%[0-9]+]]:_(s32) = G_SUB [[COPY]], [[C2]]
  ; CHECK:   [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[SUB1]](s32)
  ; CHECK:   [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 38
  ; CHECK:   [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(ugt), [[SUB1]](s32), [[C3]]
  ; CHECK:   G_BRCOND [[ICMP1]](s1), %bb.4
  ; CHECK:   G_BR %bb.7
  ; CHECK: bb.6.entry:
  ; CHECK:   successors: %bb.2(0x76276276), %bb.5(0x09d89d8a)
  ; CHECK:   [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
  ; CHECK:   [[SHL:%[0-9]+]]:_(s32) = G_SHL [[C4]], [[SUB]](s32)
  ; CHECK:   [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 57351
  ; CHECK:   [[AND:%[0-9]+]]:_(s32) = G_AND [[SHL]], [[C5]]
  ; CHECK:   [[C6:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
  ; CHECK:   [[ICMP2:%[0-9]+]]:_(s1) = G_ICMP intpred(ne), [[AND]](s32), [[C6]]
  ; CHECK:   G_BRCOND [[ICMP2]](s1), %bb.2
  ; CHECK:   G_BR %bb.5
  ; CHECK: bb.7.entry:
  ; CHECK:   successors: %bb.3(0x71c71c72), %bb.4(0x0e38e38e)
  ; CHECK:   [[C7:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
  ; CHECK:   [[SHL1:%[0-9]+]]:_(s64) = G_SHL [[C7]], [[ZEXT]](s64)
  ; CHECK:   [[C8:%[0-9]+]]:_(s64) = G_CONSTANT i64 365072220160
  ; CHECK:   [[AND1:%[0-9]+]]:_(s64) = G_AND [[SHL1]], [[C8]]
  ; CHECK:   [[C9:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
  ; CHECK:   [[ICMP3:%[0-9]+]]:_(s1) = G_ICMP intpred(ne), [[AND1]](s64), [[C9]]
  ; CHECK:   G_BRCOND [[ICMP3]](s1), %bb.3
  ; CHECK:   G_BR %bb.4
  ; CHECK: bb.2.sw.bb37:
  ; CHECK:   TCRETURNdi @callee, 0, csr_aarch64_aapcs, implicit $sp
  ; CHECK: bb.3.sw.bb55:
  ; CHECK:   TCRETURNdi @callee, 0, csr_aarch64_aapcs, implicit $sp
  ; CHECK: bb.4.sw.default:
  ; CHECK:   RET_ReallyLR
entry:
  switch i32 %p, label %sw.default [
    i32 32, label %sw.bb55
    i32 34, label %sw.bb55
    i32 36, label %sw.bb55
    i32 191, label %sw.bb37
    i32 190, label %sw.bb37
    i32 189, label %sw.bb37
    i32 178, label %sw.bb37
    i32 177, label %sw.bb37
    i32 176, label %sw.bb37
    i32 38, label %sw.bb55
  ]

sw.bb37:                                          ; preds = %entry, %entry, %entry, %entry, %entry, %entry
  tail call void @callee()
  ret void

sw.bb55:                                          ; preds = %entry, %entry, %entry, %entry
  tail call void @callee()
  ret void

sw.default:                                       ; preds = %entry
  ret void
}

define i32 @test_bittest_single_bt_only_with_fallthrough(i16 %p) {
  ; CHECK-LABEL: name: test_bittest_single_bt_only_with_fallthrough
  ; CHECK: bb.1 (%ir-block.0):
  ; CHECK:   successors: %bb.2(0x0aaaaaab), %bb.4(0x75555555)
  ; CHECK:   liveins: $w0
  ; CHECK:   [[COPY:%[0-9]+]]:_(s32) = COPY $w0
  ; CHECK:   [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
  ; CHECK:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
  ; CHECK:   [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
  ; CHECK:   [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC]](s16)
  ; CHECK:   [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
  ; CHECK:   [[SUB:%[0-9]+]]:_(s32) = G_SUB [[ZEXT]], [[C2]]
  ; CHECK:   [[ZEXT1:%[0-9]+]]:_(s64) = G_ZEXT [[SUB]](s32)
  ; CHECK:   [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 59
  ; CHECK:   [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(ugt), [[SUB]](s32), [[C3]]
  ; CHECK:   G_BRCOND [[ICMP]](s1), %bb.2
  ; CHECK: bb.4 (%ir-block.0):
  ; CHECK:   successors: %bb.3(0x745d1746), %bb.2(0x0ba2e8ba)
  ; CHECK:   [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
  ; CHECK:   [[SHL:%[0-9]+]]:_(s64) = G_SHL [[C4]], [[ZEXT1]](s64)
  ; CHECK:   [[C5:%[0-9]+]]:_(s64) = G_CONSTANT i64 866239240827043840
  ; CHECK:   [[AND:%[0-9]+]]:_(s64) = G_AND [[SHL]], [[C5]]
  ; CHECK:   [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
  ; CHECK:   [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(ne), [[AND]](s64), [[C6]]
  ; CHECK:   G_BRCOND [[ICMP1]](s1), %bb.3
  ; CHECK: bb.2.sw.epilog:
  ; CHECK:   $w0 = COPY [[C1]](s32)
  ; CHECK:   RET_ReallyLR implicit $w0
  ; CHECK: bb.3.cb1:
  ; CHECK:   $w0 = COPY [[C]](s32)
  ; CHECK:   RET_ReallyLR implicit $w0
  switch i16 %p, label %sw.epilog [
    i16 58, label %cb1
    i16 59, label %cb1
    i16 47, label %cb1
    i16 48, label %cb1
    i16 50, label %cb1
  ]
sw.epilog:
  ret i32 0

cb1:
  ret i32 42
}

define void @bit_test_block_incomplete_phi() {
  ; CHECK-LABEL: name: bit_test_block_incomplete_phi
  ; CHECK: bb.1.entry:
  ; CHECK:   successors: %bb.5(0x80000000)
  ; CHECK:   [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
  ; CHECK:   [[DEF1:%[0-9]+]]:_(p0) = G_IMPLICIT_DEF
  ; CHECK:   [[C:%[0-9]+]]:_(s1) = G_CONSTANT i1 false
  ; CHECK:   [[C1:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
  ; CHECK:   [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
  ; CHECK:   [[SUB:%[0-9]+]]:_(s32) = G_SUB [[DEF]], [[C2]]
  ; CHECK: bb.5.entry:
  ; CHECK:   successors: %bb.3(0x51745d17), %bb.4(0x2e8ba2e9)
  ; CHECK:   [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
  ; CHECK:   [[SHL:%[0-9]+]]:_(s32) = G_SHL [[C3]], [[SUB]](s32)
  ; CHECK:   [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 491
  ; CHECK:   [[AND:%[0-9]+]]:_(s32) = G_AND [[SHL]], [[C4]]
  ; CHECK:   [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
  ; CHECK:   [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(ne), [[AND]](s32), [[C5]]
  ; CHECK:   G_BRCOND [[ICMP]](s1), %bb.3
  ; CHECK:   G_BR %bb.4
  ; CHECK: bb.6.entry:
  ; CHECK:   successors:
  ; CHECK: bb.2.sw.epilog.i:
  ; CHECK:   successors:
  ; CHECK: bb.3.if.end:
  ; CHECK:   successors: %bb.4(0x80000000)
  ; CHECK:   [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[DEF1]](p0) :: (load (p0) from `i8** undef`)
  ; CHECK: bb.4.return:
  ; CHECK:   [[PHI:%[0-9]+]]:_(s1) = G_PHI [[C]](s1), %bb.3, [[C1]](s1), %bb.5
  ; CHECK:   RET_ReallyLR
entry:
  switch i32 undef, label %sw.epilog.i [
    i32 4, label %return
    i32 2, label %return
    i32 10, label %return
    i32 9, label %return
    i32 1, label %if.end
    i32 3, label %if.end
    i32 5, label %if.end
    i32 0, label %if.end
    i32 6, label %if.end
    i32 7, label %if.end
    i32 8, label %if.end
  ]

sw.epilog.i:                                      ; preds = %entry
  unreachable

if.end:                                           ; preds = %entry, %entry, %entry, %entry, %entry, %entry, %entry
  %0 = load i8*, i8** undef, align 8
  br label %return

return:                                           ; preds = %if.end, %entry, %entry, %entry, %entry
  %retval.0 = phi i1 [ false, %if.end ], [ true, %entry ], [ true, %entry ], [ true, %entry ], [ true, %entry ]
  ret void
}
